<template>
    <div class="drawBoardSvg">
        <h1>SVG小白板</h1>
        <div class="content">
            <div class="top">
                <span v-if="type !== ''">颜色</span>
                <el-color-picker
                    v-model="color"
                    show-alpha
                    size="medium"
                    :predefine="pre"
                    @change="setFontColor"
                    v-if="type !== ''"
                ></el-color-picker>
                <span v-if="type === 'text'">字号</span>
                <el-select
                    v-model="fontSize"
                    placeholder="请选择字号"
                    v-if="type === 'text'"
                >
                    <el-option
                        v-for="item in options"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                    >
                    </el-option>
                </el-select>
                <span v-if="type !== 'text' && type !== ''">线宽度</span>
                <el-select
                    v-model="lineWidth"
                    placeholder="请选择"
                    v-if="type !== 'text' && type !== ''"
                >
                    <el-option
                        v-for="item in lines"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                    >
                    </el-option>
                </el-select>
                <span v-if="type === 'rect' && type !== ''">圆角</span>
                <el-select
                    v-model="degree"
                    placeholder="请选择"
                    v-if="type === 'rect' && type !== ''"
                >
                    <el-option
                        v-for="item in degrees"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                    >
                    </el-option>
                </el-select>
                <span
                    v-if="
                        ['text', 'line', 'polyline', 'path'].indexOf(type) ===
                            -1 && type !== ''
                    "
                    >背景色</span
                >
                <el-switch
                    v-model="bgOpen"
                    active-color="#13ce66"
                    inactive-color="#ff4949"
                    @change="bgOpens()"
                    v-if="
                        ['text', 'line', 'polyline', 'path'].indexOf(type) ===
                            -1 && type !== ''
                    "
                >
                </el-switch>
                <el-color-picker
                    v-model="bgColor"
                    show-alpha
                    size="medium"
                    :predefine="bgColorS"
                    v-if="type !== 'text' && type !== '' && bgOpen"
                ></el-color-picker>
            </div>
            <div class="con">
                <div class="left">
                    <el-button @click="setDraw('rect')">矩形</el-button>
                    <el-button @click="setDraw('circle')">圆形</el-button>
                    <el-button @click="setDraw('ellipse')">椭圆</el-button>
                    <!--<el-button @click="setDraw('polygon')">多边形</el-button>-->
                    <el-button @click="setDraw('text')">文字</el-button>
                    <el-button @click="setDraw('polyline')">画笔</el-button>
                    <el-button @click="setDraw('line')">直线</el-button>
                    <el-button @click="back()">回退</el-button>
                    <el-button @click="clear()">清屏</el-button>
                </div>
                <div
                    class="tx right"
                    id="svgs"
                    @mousedown="mDown"
                    @mouseup="mUp"
                    @mousemove="mMove"
                ></div>
            </div>
            <div class="bottom">
                <el-input
                    v-model="value"
                    placeholder="请输入内容"
                    v-if="type === 'text'"
                    @input="setVaule(true)"
                    @change="setVaule(false)"
                ></el-input>
            </div>
        </div>
    </div>
</template>
<script>
import { SVG } from '@svgdotjs/svg.js';
export default {
    layout: 'blank',
    data() {
        return {
            type: '', //形状类型
            svgDraw: null,
            point: 'up', //鼠标是否按下0未按下1已按下2松开
            x: 0,
            y: 0,
            polylineList: [], //曲线
            paths: '', //路径
            polygonList: [], //多边形
            idNum: 0,
            options: [
                {
                    value: '12',
                    label: '12号字'
                },
                {
                    value: '14',
                    label: '14号字'
                },
                {
                    value: '16',
                    label: '16号字'
                },
                {
                    value: '18',
                    label: '18号字'
                },
                {
                    value: '20',
                    label: '20号字'
                },
                {
                    value: '24',
                    label: '24号字'
                }
            ],
            fontSize: '14',
            color: 'rgba(0,0,0,1)',
            pre: ['rgba(255,255,255,1)', 'rgba(0,0,0,1)'],
            value: '', //输入框文字
            lineWidth: '1', //线宽度
            lines: [
                {
                    value: '1',
                    label: '1'
                },
                {
                    value: '2',
                    label: '2'
                },
                {
                    value: '3',
                    label: '3'
                },
                {
                    value: '4',
                    label: '4'
                },
                {
                    value: '5',
                    label: '5'
                },
                {
                    value: '6',
                    label: '6'
                },
                {
                    value: '7',
                    label: '7'
                },
                {
                    value: '8',
                    label: '8'
                },
                {
                    value: '9',
                    label: '9'
                },
                {
                    value: '10',
                    label: '10'
                }
            ],
            degree: '0', //角度
            degrees: [
                {
                    value: '0',
                    label: '0'
                },
                {
                    value: '10',
                    label: '10'
                },
                {
                    value: '15',
                    label: '15'
                },
                {
                    value: '30',
                    label: '30'
                },
                {
                    value: '45',
                    label: '45'
                },
                {
                    value: '50',
                    label: '50'
                },
                {
                    value: '60',
                    label: '60'
                }
            ],
            bgOpen: false,
            bgColor: 'rgba(255,255,255,1)',
            bgColorS: ['rgba(255,255,255,1)', 'rgba(0,0,0,1)']
        };
    },
    mounted() {
        this.svgDraw = SVG()
            .addTo('.tx')
            .size('100%', '100%');
    },
    methods: {
        //绘制外边框
        getPath(x, y, x1, y1) {
            if (x > x1) {
                x += 10;
                x1 -= 10;
            } else {
                x -= 10;
                x1 += 10;
            }
            if (y > y1) {
                y += 10;
                y1 -= 10;
            } else {
                y -= 10;
                y1 += 10;
            }
            let string = `M${x},${y},L${x1},${y},L${x1},${y1},L${x},${y1}Z`;
            this.svgDraw
                .path(string)
                .fill('none')
                .stroke({ width: 2, color: 'red', dasharray: '5,5' })
                .style({
                    cursor: 'move'
                });
        },
        setPath(x, y, x1, y1) {
            let type = this.type;
            switch (type) {
                case 'rect':
                    this.getPath(x, y, x1, y1);
                    break;
                case 'circle':
                    let r1 = Math.abs(x - x1);
                    let r2 = Math.abs(y - y1);
                    let r = Math.sqrt(Math.pow(r1, 2) + Math.pow(r2, 2)); //求半径
                    this.getPath(x - r, y + r, x + r, y - r);
                    break;
                case 'ellipse':
                    let r3 = Math.abs(x - x1);
                    let r4 = Math.abs(y - y1);
                    this.getPath(x - r3, y + r4, x + r3, y - r4);
                    break;
                case 'line':
                    this.getPath(x, y, x1, y1);
                    break;
                case 'polyline':
                    console.log(this.polylineList);
                    const even = this.polylineList.filter(
                        (_item, index) => index % 2 === 0
                    ); //偶数下标 （x）
                    const odd = this.polylineList.filter(
                        (_item, index) => index % 2 !== 0
                    ); //奇数下标 (y)
                    const xMax = Math.max.apply(null, even); //x最大值
                    const xMin = Math.min.apply(null, even); //x最小值
                    const yMax = Math.max.apply(null, odd); //y最大值
                    const yMin = Math.min.apply(null, odd); //y最小值
                    this.getPath(xMin, yMax, xMax, yMin);
                    break;
                default:
                    break;
            }
        },
        //鼠标抬起
        mUp(e) {
            this.draw(this.x, this.y, e.offsetX, e.offsetY, 'up');
        },
        //鼠标移动
        mMove(e) {
            if (this.point === 'down' || this.point === 'move') {
                this.draw(this.x, this.y, e.offsetX, e.offsetY, 'move');
            }
        },
        //获取鼠标点击坐标
        mDown(e) {
            if (this.type === '') {
                this.$message.error('未选择工具');
                return;
            }
            if (this.type === 'text') this.value = '';
            this.x = e.offsetX; //获取相对坐标
            this.y = e.offsetY;
            this.draw(this.x, this.y, this.x, this.y, 'down');
        },
        //获取需要绘制类型
        setDraw(type) {
            this.type = type;
            this.color = 'rgba(0,0,0,1)';
            this.lineWidth = '1';
            this.degree = '0';
            this.bgOpen = false;
            this.bgColor = 'none';
            console.log('需要绘制图形：', type);
        },

        //绘制图形
        async draw(x, y, x1 = 0, y1 = 0, status = 'move') {
            console.log(x, y, x1, y1, status);
            let type = this.type;
            this.point = status;
            if (this.type === 'polyline') {
                this.polylineList.push(x1, y1);
                if (this.point === 'up') {
                    this.paths = await this.polyline2path(this.polylineList);
                    type = 'path';
                }
            } else if (this.type === 'polygon') {
                if (this.point === 'down' || this.point === 'up')
                    this.polygonList.push(x1, y1);
            }

            if (this.point === 'down') {
                this.idNum += 1;
            } else if (this.point === 'move' || this.point === 'up') {
                this.back(); //屏蔽掉会有好玩效果
            }
            switch (type) {
                case 'rect':
                    let w = Math.abs(x - x1);
                    let h = Math.abs(y - y1);
                    this.svgDraw
                        .rect(w, h)
                        .fill(this.bgColor)
                        .radius(Number(this.degree))
                        .stroke({ width: this.lineWidth, color: this.color })
                        .attr({
                            x: x > x1 ? x1 : x,
                            y: y > y1 ? y1 : y,
                            id: `c_${this.idNum}`
                        });
                    break;
                case 'circle':
                    let r1 = Math.abs(x - x1);
                    let r2 = Math.abs(y - y1);
                    let r = Math.sqrt(Math.pow(r1, 2) + Math.pow(r2, 2)); //求半径
                    this.svgDraw
                        .circle(r * 2)
                        .fill(this.bgColor)
                        .stroke({ width: this.lineWidth, color: this.color })
                        .attr({
                            cx: x,
                            cy: y,
                            id: `c_${this.idNum}`
                        });
                    break;
                case 'text':
                    this.svgDraw
                        .text(this.value)
                        .fill(this.color)
                        .attr({
                            x: x,
                            y: y,
                            id: `c_${this.idNum}`
                        })
                        .font({
                            size: this.fontSize
                        });
                    break;
                case 'polyline':
                    this.svgDraw
                        .polyline(this.polylineList)
                        .fill('none')
                        .stroke({ width: this.lineWidth, color: this.color })
                        .attr({
                            id: `c_${this.idNum}`
                        });

                    break;
                case 'line':
                    this.svgDraw
                        .line(x, y, x1, y1)
                        .fill('none')
                        .stroke({ width: this.lineWidth, color: this.color })
                        .attr({
                            id: `c_${this.idNum}`
                        });
                    break;
                case 'path':
                    this.svgDraw
                        .path(this.paths)
                        .fill('none')
                        .stroke({ width: this.lineWidth, color: this.color })
                        .attr({
                            id: `c_${this.idNum}`
                        });

                    break;
                case 'polygon':
                    this.svgDraw
                        .polygon(this.polygonList)
                        .fill(this.bgColor)
                        .stroke({ width: this.lineWidth, color: this.color })
                        .attr({
                            id: `c_${this.idNum}`
                        });

                    break;
                case 'ellipse':
                    let r3 = Math.abs(x - x1);
                    let r4 = Math.abs(y - y1);
                    this.svgDraw
                        .ellipse(r3 * 2, r4 * 2)
                        .fill(this.bgColor)
                        .stroke({ width: this.lineWidth, color: this.color })
                        .attr({
                            cx: x,
                            cy: y,
                            id: `c_${this.idNum}`
                        });
                    break;
                default:
                    break;
            }
            if (this.point === 'up') {
                this.setPath(x, y, x1, y1);
                if (type === 'polygon') this.polygonList = [];
                if (type === 'path') {
                    this.polylineList = [];
                    this.paths = '';
                }
            }
        },

        dj(id) {
            console.log(id);
        },
        //设置字体颜色
        setFontColor() {
            console.log(this.color);
        },
        //设置文本
        setVaule(status) {
            status ? this.draw(this.x, this.y, 0, 0, 'up') : this.value === '';
        },
        //是否开始背景颜色
        bgOpens() {
            this.bgColor = this.bgOpen ? 'rgba(255,255,255,1)' : 'none';
        },
        //回退
        back() {
            const csvg = document.getElementById('svgs').childNodes[0];
            const childs = csvg.childNodes;
            let len = childs.length;
            if(len===0) return;
            csvg.removeChild(childs[len - 1]);
        },
        //清屏
        clear() {
            const csvg = document.getElementById('svgs').childNodes[0];
            const childs = csvg.childNodes;
            //循环遍历的时候一定要倒序，因为正序的时候，当你把索引为0的子节点删除后，那么原来索引为1的就变成了0，而这时变量 i 已经变成1了，程序继续走时就会删除原先索引为２的现在为1的节点，结果就是最后只删除了一半的节点
            for (let i = childs.length - 1; i >= 0; i--) {
                csvg.removeChild(childs[i]);
            }
            this.idNum = 0;
            this.value = '';
        },
        //曲线转path
        polyline2path(points) {
            let path =
                'M' +
                points.slice(0, 2).join(',') +
                'L' +
                points.slice(2).join(',');
            return path;
        }
    }
};
</script>
<style lang="less" scoped>
.drawBoardSvg {
    height: 100%;
    width: calc(100% - 80px);
    margin: 0 auto;
    h1 {
        text-align: center;
        height: 60px;
        display: flex;
        align-items: center;
        flex-direction: column-reverse;
    }
    .content {
        height: calc(100% - 80px);
        .top {
            height: 60px;
            display: flex;
            align-items: center;
        }
        .con {
            display: flex;
            align-items: center;
            height: calc(100% - 140px);
            .left {
                width: 90px;
                height: 100%;
                border: 1px solid;
                .action {
                }
            }
            .right {
                height: 100%;
                width: calc(100% - 90px);
                border: 1px solid;
            }
        }
        .bottom {
            height: 80px;
            display: flex;
            align-items: center;
        }
    }
}
</style>
<style lang="less">
.drawBoardSvg {
    .con {
        .left {
            .el-button {
                width: 90px;
                margin: 0px;
            }
        }
    }
}
</style>
